package com.koron.device.controller;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.koron.bean.base.Constants;
import com.koron.bean.base.Response;
import com.koron.bean.plan.patrol.po.PatrolEquipmentParamsPo;
import com.koron.bean.query.PageQuery;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.annocation.CasUser;
import com.koron.common.core.business.common.entity.EqCodeBean;
import com.koron.common.core.business.common.mapper.EqCodeBeanMapper;
import com.koron.common.core.business.configsettings.utils.ConfigInfoTool;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.*;
import com.koron.common.core.util.dfs.FastDFSClientWrapper;
import com.koron.device.bean.*;
import com.koron.device.bean.dto.BatchMoveNodeDto;
import com.koron.device.bean.dto.LineEquipmentVo;
import com.koron.device.bean.po.EquipmentParamsPo;
import com.koron.device.bean.po.EquipmentPo;
import com.koron.device.bean.query.AdvancedQuery;
import com.koron.device.bean.query.ERcodeQuery;
import com.koron.device.bean.query.EqParamQuery;
import com.koron.device.bean.template.EquipmentErrorMsg;
import com.koron.device.bean.template.EquipmentTemplate;
import com.koron.device.bean.template.ImPMsgDto;
import com.koron.device.feign.OrderFeignService;
import com.koron.device.mapper.CTypeMapper;
import com.koron.device.mapper.EquipmentLocationMapper;
import com.koron.device.mapper.EquipmentMapper;
import com.koron.device.mapper.TypeParamsMapper;
import com.koron.device.service.EquipmentService;
import com.koron.device.utils.DeviceUtils;
import com.koron.device.utils.EqExportOrImpUtils;
import com.koron.device.utils.EqtempInitData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.koron.ebs.mybatis.ADOConnection;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author qingfeng
 * @description: TODO
 * @date 2021/7/7 17:45
 */
@Slf4j
@RequestMapping("/equipment")
@RestController
@Api(tags = "设备管理")
public class EquipmentController {

    @Autowired
    private EquipmentService equipmentservice;

    @Autowired
    private OrderFeignService orderFeignService;

    @PostMapping("/insert")
    @ApiOperation(value = "新增设备")
    public Response insert(@CasUser @ApiIgnore EamUser user, @RequestBody Equipment equipment) {
        DisposeBeanUtil.disposeInsert(user, equipment);
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "insert", Response.class, equipment);
    }

    @PostMapping("/update")
    @ApiOperation(value = "修改设备")
    public Response update(@CasUser @ApiIgnore EamUser user, @RequestBody Equipment equipment) {
        DisposeBeanUtil.disposeUpdate(user, equipment);
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "update", Response.class, equipment);
    }

    @GetMapping("/delete")
    @ApiOperation(value = "删除设备")
    public Response delete(@CasUser @ApiIgnore EamUser user, String id) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "delete", Response.class, id);
    }

    /**
     * 根据id或code查询设备详情，由于小程序生成二维码的参数scene不得超过32个字符，故使用code查询
     *
     * @param id   设备id
     * @param code 设备编码
     * @return
     */
    @GetMapping("/getById")
    @ApiOperation(value = "根据id或code查询单个设备")
    public Response<Equipment> getById(String id, String code, String encode, String origin) {
        // 兼容eam1.0工单设备不存在报错提示
        if ("eam.1.0".equals(origin)){
            return Response.success();
        }
        return ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), equipmentservice, "getById", Response.class, id, code, encode);
    }

    //@GetMapping("/getTree")
    @ApiOperation(value = "查询设备台账树形结构")
    @Deprecated
    public Response<List<Equipment>> getTree(@CasUser @ApiIgnore EamUser user) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getTree", Response.class);
    }

    @GetMapping("/getTreeLazy")
    @ApiOperation(value = "查询设备台账树形结构（懒加载）, configRules：属性值")
    public Response<List<Equipment>> getTreeLazy(@CasUser @ApiIgnore EamUser user, EquipmentQuery query) {
        query.getConfigRules().add("hasChildren");
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getTreeLazy", Response.class, query);
    }

    @GetMapping("/getBasicParamsByTypeId")
    @ApiOperation(value = "根据分类id查询基础参数列表")
    public Response<List<EquipmentParams>> getBasicParamsByTypeId(@CasUser @ApiIgnore EamUser user, String typeId) {
        return equipmentservice.getBasicParamsByTypeId(typeId);
    }

    @GetMapping("/getTechParamsByTypeId")
    @ApiOperation(value = "根据分类id查询技术参数列表")
    public Response<List<EquipmentParams>> getTechParamsByTypeId(@CasUser @ApiIgnore EamUser user, String typeId) {
        return equipmentservice.getTechParamsByTypeId(typeId);
    }

    @GetMapping("/getParamsByTypeId")
    @ApiOperation(value = "根据分类id查询参数列表")
    public Response<Map<String, List<EquipmentParams>>> getParamsByTypeId(@CasUser @ApiIgnore EamUser user, String typeId) {
        return Response.succ(equipmentservice.getParamsByTypeId(typeId));
    }

    @GetMapping("/getGenericParams")
    @ApiOperation(value = "获取设备常用参数值")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "设备分类id", name = "typeId", required = false),
            @ApiImplicitParam(value = "设备id", name = "equipmentId", required = true)
    })
    public Response<Map<String, EquipmentParams>> getGenericParams(@CasUser @ApiIgnore EamUser user, String equipmentId) {
        return Response.succ(ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getGenericParam", Map.class, equipmentId));
    }

    @PostMapping("/getBatchGenericParams")
    @ApiOperation(value = "获取设备常用参数值")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "设备id集合", name = "equipmentIds", required = true)
    })
    public Response<Map<String, Map<String, EquipmentParams>>> getBatchGenericParams(@CasUser @ApiIgnore EamUser user, @RequestBody List<String> equipmentIds) {
        return Response.succ(ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getGenericParams", Map.class, equipmentIds));
    }

    @PostMapping("/getBatchBaseParams")
    @ApiOperation(value = "获取设备参数值")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "设备id集合", name = "equipmentIds", required = true)
    })
    public Response<List<EquipmentParams>> getBatchBaseParams(@CasUser @ApiIgnore EamUser user, @RequestBody List<String> equipmentIds) {
        return Response.succ(ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getBatchBaseParams", List.class, equipmentIds));
    }

//    @GetMapping("/moveNode")
//    @ApiOperation(value = "移动节点")
//    public Response moveNode(@CasUser @ApiIgnore EamUser user, @ApiParam("节点id") String id, @ApiParam("移动至父节点id，移动至根节点不传") String parentId, @ApiParam("排序") Integer sort) {
//        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "moveNode", Response.class, id, parentId, sort);
//    }

    @GetMapping("/moveNode")
    @ApiOperation(value = "移动节点")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "节点id", name = "id", required = true),
            @ApiImplicitParam(value = "移动至父节点id，移动至根节点不传", name = "parentId", required = true),
            @ApiImplicitParam(value = "排序", name = "sort", required = false)
    })
    public Response moveNode(@CasUser @ApiIgnore EamUser user, String id, String parentId, Integer sort) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "moveNode", Response.class, id, parentId, sort);
    }

    @PostMapping("/batchMoveNode")
    @ApiOperation(value = "移动节点")
    public Response batchMoveNode(@CasUser @ApiIgnore EamUser user, @RequestBody BatchMoveNodeDto dto) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "batchMoveNode", Response.class, dto.getMovelist(), dto.getTargetId(), dto.getSort());
    }

    @GetMapping("/drag")
    @ApiOperation(value = "同级拖拽排序")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "拖拽id", name = "dragId", required = true),
            @ApiImplicitParam(value = "目标id", name = "targetId", required = true),
            @ApiImplicitParam(value = "after or before", name = "position", required = true),
    })
    public Response drag(@CasUser @ApiIgnore EamUser user, @RequestParam("dragId") String dragId, @RequestParam("targetId") String targetId, @RequestParam("position") String position) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "drag", Response.class, dragId, targetId, position);
    }

    @GetMapping("/dragView")
    @ApiOperation(value = "拖拽界面")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "目标id", name = "targetId", required = true),
    })
    public Response dragView(@CasUser @ApiIgnore EamUser user, @RequestParam("targetId") String targetId) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "dragView", Response.class, targetId);
    }

    @GetMapping("/moveMoreNode")
    @ApiOperation(value = "移动多个节点")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "节点id", name = "id", required = true),
            @ApiImplicitParam(value = "移动至父节点id，移动至根节点不传", name = "parentId", required = true),

    })
    public Response moveMoreNode(@CasUser @ApiIgnore EamUser user, @RequestParam("ids") List<String> ids,@RequestParam("parentId") String parentId) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "moveMoreNode", Response.class, ids, parentId);
    }


    @GetMapping("/getFloor")
    @ApiOperation(value = "获取层级列表")
    public Response<List<Select>> getFloor(@CasUser @ApiIgnore EamUser user, String parentId, String id) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getFloor", Response.class, parentId, id);
    }

    @GetMapping({"/searchByName", "/queryList"})
    @ApiOperation(value = "根据设备名称模糊查询, page或pageSize小于等于0时不分页，分页与不分页，返回结构不一样")
    public Response<Object> queryList(@CasUser @ApiIgnore EamUser user, EquipmentQuery query) {
        if (query.getPage() > 0 && query.getPageSize() > 0) {
            PageHelper.startPage(query.getPage(), query.getPageSize());
            List equipments = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "queryList", List.class, query);
            return Response.ok(new PageInfo<>(equipments));
        } else {
            List equipments = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "queryList", List.class, query);
            return Response.ok(equipments);
        }
    }

    private EamUser getCurrUser() {
        return ThreadLocalContext.get();
    }

    @GetMapping("/getParamsByResult")
    @ApiOperation(value = "根据设备参数值精确查询")
    public Response<List<Equipment>> getParamsByResult(String paramResult) {
        return ADOConnection.runTask(getCurrUser().getCurrDs(), equipmentservice, "getParamsByResult", Response.class, paramResult);
    }

    @GetMapping("/getParentIds")
    @ApiOperation(value = "获取某个节点的所有父节点")
    public Response<List<String>> getParentIds(@CasUser @ApiIgnore EamUser user, String id) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getParentIds", Response.class, id);
    }

    @GetMapping("/getEquipmentByLocation")
    @ApiOperation(value = "根据位置id查询当前的设备")
    public Response<List<Equipment>> getEquipmentByLocation(@CasUser @ApiIgnore EamUser user, String locationId) {
        List<Equipment> equipments = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getEquipmentByLocation", List.class, locationId);
        return Response.ok(equipments);
    }

    @GetMapping("/getLeftUpperEquipmentByDeptId")
    @ApiOperation(value = "获取同组织下，最左上的设备台账")
    public Response<Equipment> getLeftUpperEquipmentByDeptId(@CasUser @ApiIgnore EamUser user, String deptId, String managerUnit) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getLeftUpperEquipmentByDeptId", Response.class, deptId, managerUnit);
    }

    @GetMapping("/getParamById")
    @ApiOperation(value = "根据参数id查询参数")
    public Response<Equipment> getParamById(@CasUser @ApiIgnore EamUser user, String paramId) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getParamById", Response.class, paramId);
    }

    @ApiOperation(value = "人工记录")
    @GetMapping("/params/queryList")
    public Response<Object> queryPageList(PatrolEquipmentParamsPo queryPo, PageQuery pageQuery) {
        return orderFeignService.queryPageList(queryPo, pageQuery);
    }

    @ApiOperation(value = "导出所有设备")
    @GetMapping("/export")
    @ApiImplicitParam(value = "设备id，不传导出全部", name = "equipmentId")
    public void export(@CasUser @ApiIgnore EamUser user, HttpServletResponse resp, @RequestParam(required = false) String equipmentId, String fileName) {
        if (StringUtils.isBlank(fileName)) {
            fileName = "设备列表";
        }
        if (StringUtils.isBlank(FileUtil.extName(fileName))) {
            fileName += ".xlsx";
        }
        List<EquipmentExcel> excels = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "export", List.class, equipmentId);
        EasyExcelUtils.export(resp, FileUtil.mainName(fileName), excels, fileName);
    }

    @ApiOperation(value = "设备树修正")
    @GetMapping("/rectify")
    public Response<Boolean> rectify(@CasUser @ApiIgnore EamUser user) {
        Boolean rectify = ADOConnection.runTask(user.getCurrDs(), new DeviceUtils(), "deviceRectify", Boolean.class);
        return Response.ok(rectify);
    }

    @ApiOperation(value = "导出台账模板")
    @GetMapping("/downEquipmentTemplate")
    public void downEquipmentTemplate(HttpServletResponse rsp) {
        List<EquipmentTemplate> list = new ArrayList<>();
        try {
            EqtempInitData.initEquipmentData(list);
            ExportExcelUtil.exportExcel(list, EquipmentTemplate.class, "台账模板", rsp);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @ApiOperation(value = "台账导入")
    @PostMapping("/importEquipment")
    public Response<ImPMsgDto> importEquipment(@CasUser @ApiIgnore EamUser user, @RequestParam("file") MultipartFile multipartFile, @RequestParam(value = "id", required = false) String id) throws Exception {
        ExcelImportResult<EquipmentTemplate> result;
        ImportParams params = new ImportParams();
        // 表头设置为2行
        params.setHeadRows(1);
        // 标题行设置为0行，默认是0，可以不设置
        params.setTitleRows(0);
        result = ExcelImportUtil.importExcelMore(multipartFile.getInputStream(), EquipmentTemplate.class, params);
        List<EquipmentTemplate> list = result.getList();

        //获取所有设备分类
        CTypePo cTypePo = ADOConnection.runTask(sessionFactory -> {
            List<CType> cTypes = sessionFactory.getMapper(CTypeMapper.class).queryByAll(null);
            Map<String, String> typeCodeNamemap = cTypes.stream().collect(Collectors.toMap(CType::getCode, CType::getName, (c1, c2) -> c1));
            Map<String, String> typeCodeIdmap = cTypes.stream().collect(Collectors.toMap(CType::getCode, CType::getId, (c1, c2) -> c1));
            List<String> codelist = cTypes.stream().map(CType::getCode).distinct().collect(Collectors.toList());
            List<String> namelist = cTypes.stream().map(CType::getName).distinct().collect(Collectors.toList());
            CTypePo temp = new CTypePo(typeCodeNamemap, typeCodeIdmap, codelist, namelist);
            return temp;
        }, CTypePo.class);

        //获取父级台账
        Equipment parentEq = ADOConnection.runTask(user.getCurrDs(), sessionFactory -> {
            //不传父id默认在 系统默认根节点下建立树结构
            String parentId = StrUtil.isBlank(id) ? Constants.DEVICE_TREE_ROOT_CODE : id;
            return sessionFactory.getMapper(EquipmentMapper.class).getById(parentId,null);
        }, Equipment.class);

        //数据校验
        List<EquipmentErrorMsg> checklist = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "importEquipment", List.class, list, parentEq, cTypePo);

        if (checklist.stream().anyMatch(c -> StrUtil.isNotBlank(c.getErrorMsg()))) {

            String time = String.valueOf(DateUtil.currentSeconds());
            String fileName = ExportExcelUtil.saveExcel(checklist, EquipmentErrorMsg.class, "错误信息" + time + ".xls");
            return Response.ok(new ImPMsgDto("ERROR", "导入异常", fileName));
        }

        //数据构建 入库
        ADOConnection.runTask(user.getCurrDs(), equipmentservice, "buildEquipment", List.class, checklist, parentEq, cTypePo);

        return Response.ok(new ImPMsgDto("SUCCESS", "导入成功", ""));
    }


    @ApiOperation(value = "台账导入BK")
    @PostMapping("/importEquipmentBK")
    public Response<ImPMsgDto> importEquipmentBk(@CasUser @ApiIgnore EamUser user, @RequestParam("file") MultipartFile multipartFile, @RequestParam(value = "id", required = false) String id) throws Exception {
        ExcelImportResult<EquipmentTemplate> result;
        ImportParams params = new ImportParams();
        // 表头设置为2行
        params.setHeadRows(1);
        // 标题行设置为0行，默认是0，可以不设置
        params.setTitleRows(0);
        result = ExcelImportUtil.importExcelMore(multipartFile.getInputStream(), EquipmentTemplate.class, params);
        List<EquipmentTemplate> list = result.getList();
        log.info("导入结果：{}",list);
        //获取所有设备分类
        CTypePo cTypePo = ADOConnection.runTask(sessionFactory -> {
            List<CType> cTypes = sessionFactory.getMapper(CTypeMapper.class).queryByAll(null);
            Map<String, String> typeCodeNamemap = cTypes.stream().collect(Collectors.toMap(CType::getCode, CType::getName, (c1, c2) -> c1));
            Map<String, String> typeCodeIdmap = cTypes.stream().collect(Collectors.toMap(CType::getCode, CType::getId, (c1, c2) -> c1));
            List<String> codelist = cTypes.stream().map(CType::getCode).distinct().collect(Collectors.toList());
            List<String> namelist = cTypes.stream().map(CType::getName).distinct().collect(Collectors.toList());
            CTypePo temp = new CTypePo(typeCodeNamemap, typeCodeIdmap, codelist, namelist);
            return temp;
        }, CTypePo.class);

        //获取父级台账
        Equipment parentEq = ADOConnection.runTask(user.getCurrDs(), sessionFactory -> {
            //不传父id默认在 系统默认根节点下建立树结构
            String parentId = StrUtil.isBlank(id) ? Constants.DEVICE_TREE_ROOT_CODE : id;
            return sessionFactory.getMapper(EquipmentMapper.class).getById(parentId,null);
        }, Equipment.class);

        //数据校验
        List<EquipmentErrorMsg> checklist = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "importEquipment", List.class, list, parentEq, cTypePo);

        if (checklist.stream().anyMatch(c -> StrUtil.isNotBlank(c.getErrorMsg()))) {

            String time = String.valueOf(DateUtil.currentSeconds());
            String fileName = ExportExcelUtil.saveExcel(checklist, EquipmentErrorMsg.class, "错误信息" + time + ".xls");
            return Response.ok(new ImPMsgDto("ERROR", "导入异常", fileName));
        }

        //数据构建 入库
        ADOConnection.runTask(user.getCurrDs(), equipmentservice, "buildEquipment", List.class, checklist, parentEq, cTypePo);

        return Response.ok(new ImPMsgDto("SUCCESS", "导入成功", ""));
    }

    /**
     * 下载设备导入错误表格
     *
     * @return
     */
    @ApiOperation("---下载设备导入错误表格")
    @GetMapping("/errorEqExport")
    public void errorExport(@RequestParam(value = "filename") String filename, HttpServletResponse response) {
        log.info("导入错误信息路径" + filename);
        try {
            String[] names = filename.split(",");
            if (names.length == 1) {
                String path = ExportExcelUtil.getLocationPath(names[0]);
                HttpClient.downLoadCommon(response, FileUtil.file(path), filename);
                return;
            }
        } catch (Exception e) {
            log.error("下载导入错误信息异常");
            log.error(e.getMessage(), e);
        }
    }


    /**
     * fdfs客户端
     */
    @Autowired
    private FastDFSClientWrapper fdfsCient;

//    @Autowired
//    private DefaultFastFileStorageClient storageClient;

//    private RestTemplate template = new RestTemplate();

//    @Autowired
//    private QywxProperties qywxProperties;
//
//    @Autowired
//    private WxProgramMessageUtil wxProgramUtil;

    @ApiOperation("--冗余台账二维码只冗余设备、部件")
    @GetMapping("/generateERcode")
    public void generateERcode() {

        ADOConnection.runTask(getCurrUser().getCurrDs(), factory -> {
            EquipmentMapper mapper = factory.getMapper(EquipmentMapper.class);
            EqCodeBeanMapper eqcodemapper = factory.getMapper(EqCodeBeanMapper.class);

            // 设备级、部件级 做二维码冗余
            List<Equipment> list = mapper.queryByFloorIn(CollUtil.newArrayList("5", "6"));

            List<EqCodeBean> eqcodlist = eqcodemapper.queryAll();
            List<String> existlist = eqcodlist.stream().map(EqCodeBean::getEquipmentId).collect(Collectors.toList());

            List<EqCodeBean> insertlist = new ArrayList();
            int num = 1;
            for (Equipment bean : list) {
                if (existlist.contains(bean.getId())) {
                    continue;
                }
                //release 正式环境
                File file = equipmentservice.createMiniProgramQRCode(bean.getId(), bean.getName(), "release");
                //每2000次睡眠1秒钟
                if (num % 2000 == 0) {
                    sleep(60 * 1000);
                }
                num = num + 1;

                // 上传二维码图片
                EqCodeBean eqcode = uploadERcodeImg(bean, file, "release");
                insertlist.add(eqcode);
            }

            Lists.partition(insertlist, 300).stream().forEach(p -> {
                eqcodemapper.batchInsert(p);
            });
            return true;
        }, Boolean.class);

        return;
    }

    /**
     * 上传台账二维码img
     *
     * @param bean
     * @param file
     * @return
     */
    private EqCodeBean uploadERcodeImg(Equipment bean, File file, String envVersion) {
        FilesUtil filesUtil = new FilesUtil();
        MultipartFile multipartFile = filesUtil.fileToMultipartFile(file);
        log.debug("图片大小：" + multipartFile.getSize());
        String path = "";
        try {
            path = fdfsCient.uploadFile(multipartFile);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        EqCodeBean eqcode = new EqCodeBean();
        eqcode.setId(CodeTools.getCode32());
        eqcode.setEquipmentId(bean.getId());
        eqcode.setEquipmentName(bean.getName());
        eqcode.setEnvVersion(envVersion);//环境develop，release，trial
        eqcode.setEqType("eq");
        eqcode.setGroupName(StrUtil.split(path, "/").get(0));
        eqcode.setPath(path);
        eqcode.setFileSize(multipartFile.getSize());
        eqcode.setExtension("jpg");
        eqcode.setCreateTime(new Date());
        eqcode.setCreateByName(DateUtil.format(new Date(), DateTimeFormatter.ISO_LOCAL_DATE));
        return eqcode;
    }


    /**
     * 提供给common服务,对未进行冗余的台账，进行冗余
     *
     * @param eqId
     * @param name
     * @return
     */
    @GetMapping("/redundancyERcode")
    public Response<EqCodeBean> redundancyERcode(@RequestParam("eqId") String eqId, @RequestParam("name") String name, @RequestParam("envVersion") String envVersion) {
        // 生成二维码
//        File file = equipmentservice.createMiniProgramQRCode(eqId, name, envVersion);
        File file = threadDoubleGenerationERfile(eqId, name, envVersion);
        Assert.isFalse(file == null, "二维码生成异常");
        Equipment equipment = new Equipment();
        equipment.setId(eqId);
        equipment.setName(name);
        // 上传二维码
        EqCodeBean eqCodeBean = uploadERcodeImg(equipment, file, envVersion);
        ADOConnection.runTask(getCurrUser().getCurrDs(), factory -> {
            factory.getMapper(EqCodeBeanMapper.class).insertSelective(eqCodeBean);
            return true;
        }, Boolean.class);
        return Response.ok(eqCodeBean);
    }

    /**
     * 二维码生成，超时再生成
     *
     * @param eqId
     * @param name
     * @param envVersion
     * @return
     */
    private File threadDoubleGenerationERfile(String eqId, String name, String envVersion) {
        File file = null;
        // 单线程
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        // 生成二维码任务
        FutureTask<File> future = new FutureTask<File>(new Callable<File>() {
            @Override
            public File call() throws Exception {
//                Thread.sleep(10000);// 测试休眠十秒
                return equipmentservice.createMiniProgramQRCode(eqId, name, envVersion);
            }
        });
        // 执行
        executorService.execute(future);

        try {
            // 设置3秒 生成超时
            file = future.get(3, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            log.error("生成二位码中断");
            future.cancel(true);
        } catch (ExecutionException e) {
            log.error("生成二位码异常");
            // TODO: handle exception
            future.cancel(true);
        } catch (TimeoutException e) {
            // TODO: handle exception
            log.info("生成二位码超时");
            // 中断原有线程的生成任务
            future.cancel(true);
            // 超时触发式，再生成一遍
            file = equipmentservice.createMiniProgramQRCode(eqId, name, envVersion);
        }
        executorService.shutdown();
        return file;
    }

    /**
     * 休眠指定时间
     *
     * @param i 毫秒
     */
    private void sleep(long i) {
        try {
            log.info("腾讯接口限制-目前5000次/分钟 休眠开始");
            Thread.sleep(i);
            log.info("腾讯接口限制-目前5000次/分钟 休眠结束");
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        }
    }


//    public File createMiniProgramQRCode(String id, String name) {
//        Map<String, Object> param = new HashMap<>();
//        param.put("page", "pages/equiLedger/equiDetail");
//        param.put("scene", id);
//        param.put("check_path", true);
//        param.put("env_version", "trial");
//        // 请求路径url
//        String token = wxProgramUtil.getAccessTokenCache();
//        log.info("token = {}", token);
//        String url = qywxProperties.getCodeUnLimit() + "?access_token=" + token;
//        log.info("url = {}", url);
//        // 请求体body
//        HttpHeaders header = new HttpHeaders();
//        header.setContentType(MediaType.APPLICATION_JSON);
//        HttpEntity requestEntity = new HttpEntity(param, header);
//        ResponseEntity<byte[]> entity = template.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
//        HttpHeaders headers = entity.getHeaders();
//        List<String> conentTypes = headers.get("Content-Type");
//        StringBuilder sb = new StringBuilder();
//        conentTypes.stream().forEach(contentType -> sb.append(contentType));
//        Assert.isTrue(sb.toString().contains("image/jpeg"), "二维码生成失败");
//
//        File file = new File("", StrUtil.format("{}_{}.jpg", id, name));
//        FileUtil.writeBytes(entity.getBody(), file);
//
//        return file;
//    }


    @ApiOperation("--删除台账二维码")
    @GetMapping("/deleteERcode")
    public String deleteERcode(@RequestParam("list") List<String> ids) {
        return ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), factory-> {
            try {
                EqCodeBeanMapper mapper = factory.getMapper(EqCodeBeanMapper.class);
                List<EqCodeBean> attachments = mapper.queryAll();
    //            List<EqCodeBean> attachments = mapper.queryByEquipmentIdIn(ids);
                int rowNum = mapper.deleteByIdIn(attachments.stream().map(EqCodeBean::getId).collect(Collectors.toList()));
                attachments.stream().forEach(row -> fdfsCient.deleteFile(row.getPath()));
                return StrUtil.format("删除{}个", rowNum);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new RuntimeException(e.getMessage());
            }
        },String.class);
    }

    /**
     * 得到图片字节流 数组大小
     */
    public static byte[] readStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        outStream.close();
        inStream.close();
        return outStream.toByteArray();
    }


    @ApiOperation("--更新主表预设json参数")
    @GetMapping("/updateInAdvanceParam")
    public String updateInAdvanceParam() {
        List<TGParams> tplist = ADOConnection.runTask(factory -> {
            List<TGParams> tgParams = factory.getMapper(TypeParamsMapper.class).queryAll();
            List<TGParams> collect = tgParams.stream().filter(tg -> StrUtil.isNotBlank(tg.getParamCode())).collect(Collectors.toList());
            return collect;
        }, List.class);

        List<String> paramlist = tplist.stream().map(TGParams::getId).collect(Collectors.toList());
        Map<String, String> paramCodemap = tplist.stream().collect(Collectors.toMap(TGParams::getId, TGParams::getParamCode));

        ADOConnection.runTask(getCurrUser().getCurrDs(), factory -> {
            List<EquipmentParams> equipmentParams = factory.getMapper(EquipmentMapper.class).queryByParamIdIn(paramlist);
            Map<String, List<EquipmentParams>> eqmap = equipmentParams.stream().collect(Collectors.groupingBy(EquipmentParams::getEquipmentId));
            Set<Map.Entry<String, List<EquipmentParams>>> entries = eqmap.entrySet();

            List<Equipment> updateList = new ArrayList();
            for (Map.Entry<String, List<EquipmentParams>> entry : entries) {
                Equipment equipBean = new Equipment();
                equipBean.setId(entry.getKey());
                if (CollUtil.isEmpty(entry.getValue())) {
                    continue;
                }
                HashMap<String, String> map = new HashMap<>();
                for (EquipmentParams params : entry.getValue()) {
                    map.put(paramCodemap.get(params.getParamId()), params.getParamResult());
                }
                String beanToJson = FastJsonUtils.getBeanToJson(map);
                equipBean.setInAdvanceParam(beanToJson);
                updateList.add(equipBean);
            }

            Lists.partition(updateList, 300).stream().forEach(p -> {
                factory.getMapper(EquipmentMapper.class).updateInAdvanceJson(p);
            });

            return true;
        }, Boolean.class);
        return "结束";
    }


    @ApiOperation("构建-高压线塔-7个部件")
    @GetMapping("/buildGyxBj")
    public String buildGyxBj() {

        ADOConnection.runTask(getCurrUser().getCurrDs(), factory -> {
            EquipmentMapper mapper = factory.getMapper(EquipmentMapper.class);
            EquipmentLocationMapper locationMapper = factory.getMapper(EquipmentLocationMapper.class);
            List<EquipmentLocation> equipmentLocations = locationMapper.queryAll();
            // 地点名称-地点id-map
            Map<String, String> locationNameIdmap = equipmentLocations.stream().collect(Collectors.toMap(EquipmentLocation::getName, EquipmentLocation::getId, (e1, e2) -> e1));
            // 7个部件
            List<Equipment> taBjEq = mapper.getChildByParentId("0e638d6d628b427d9fc720f581744c2b");
            List<String> collect = taBjEq.stream().map(Equipment::getId).collect(Collectors.toList());
            List<EquipmentParams> equipmentParams = mapper.queryEqParamsByEqId(collect);
            // 部件id 对应 部件的参数
            Map<String, List<EquipmentParams>> eqIdParamsmap = equipmentParams.stream().collect(Collectors.groupingBy(EquipmentParams::getEquipmentId));

            // 高压线所有塔
            List<Equipment> allTower = mapper.queryAllTower();


            List<Equipment> insertbjlist = new ArrayList();
            List<EquipmentParams> insertbjprarmlist = new ArrayList();
            String yyyyMMdd = DateUtil.format(new Date(), "yyyyMMdd") + "部件导入";
            int num = 1;
            // 遍历所有塔
            for (Equipment equipment : allTower) {
                // 塔为父级
                Equipment parent = equipment;
                // 塔id
                String id = equipment.getId();
                int sort = 1;
                for (Equipment gu7bj : taBjEq) {
                    Equipment bj = new Equipment();
                    BeanUtil.copyProperties(gu7bj, bj);
                    bj.setId(CodeTools.getCode32());
                    bj.setSort(sort);
                    bj.setParentName(parent.getName());
                    bj.setParentId(parent.getId());
                    // 父级level+1
                    bj.setLevel(parent.getLevel() + 1);
                    bj.setFullPathCode(parent.getFullPathCode() + "/" + bj.getId());
                    bj.setFullPathName(parent.getFullPathName() + "/" + bj.getName());
                    bj.setIsVirtual("0");
                    int floor = Integer.valueOf(parent.getFloor()) + 1;
                    bj.setFloor(String.valueOf(floor));
                    bj.setLevelCode(sort);
                    bj.setLevelPath(parent.getLevelPath() + "/" + sort);
                    bj.setCode(getCode(num));
                    bj.setDataSources(yyyyMMdd);
                    insertbjlist.add(bj);

                    List<EquipmentParams> tabjparams = eqIdParamsmap.get(gu7bj.getId());
                    // 遍历部件相应参数
                    for (EquipmentParams bjparammo : tabjparams) {
                        EquipmentParams bjparam = new EquipmentParams();
                        BeanUtil.copyProperties(bjparammo, bjparam);
                        // 安装位置
                        if (bjparam.getParamId().equals("bb9234e1a8d94e8da4c0da10d6c13c54")) {
                            String locationId = locationNameIdmap.get(parent.getName());
                            // 相依塔名称 能在 位置表 找到 补充位置id
                            if (StrUtil.isNotBlank(locationId)) {
                                bjparam.setParamValue(parent.getName());
                                bjparam.setParamResult(locationId);
                            } else {
                                bjparam.setParamValue(null);
                                bjparam.setParamResult(null);
                            }
                        }
                        bjparam.setId(CodeTools.getCode32());
                        bjparam.setEquipmentId(bj.getId());
                        bjparam.setDataSources(yyyyMMdd);
                        insertbjprarmlist.add(bjparam);
                    }
                    sort = sort + 1;
                    num = num + 1;
                }
            }

//            int size = insertbjlist.size();
//            log.info(size);
//            long count = insertbjlist.stream().map(BaseBean::getId).distinct().count();
//            log.info(count);

            Lists.partition(insertbjlist, 300).stream().forEach(p -> {
                mapper.batchInsert(p);
            });
            Lists.partition(insertbjprarmlist, 300).stream().forEach(p -> {
                mapper.batchInsertParams(p);
            });
            return true;
        }, Boolean.class);


        return "结束";
    }

    private String getCode(Integer num) {
        String dateStr = DateFormatUtils.format(new Date(), "yyyyMMdd");
        String prefix = "E" + dateStr;
        num = num + 1;
        return prefix + String.format("%04d", num);
    }


    @ApiOperation("补充高压线部件")
    @GetMapping("/suppHighVoltComponent")
    public String suppHighVoltComponent() {

        ADOConnection.runTask(getCurrUser().getCurrDs(), factory -> {
            EquipmentMapper mapper = factory.getMapper(EquipmentMapper.class);
            EquipmentLocationMapper locationMapper = factory.getMapper(EquipmentLocationMapper.class);
            List<EquipmentLocation> equipmentLocations = locationMapper.queryAll();
            // 地点名称-地点id-map
            Map<String, String> locationNameIdmap = equipmentLocations.stream().collect(Collectors.toMap(EquipmentLocation::getName, EquipmentLocation::getId, (e1, e2) -> e1));


            // 查出补充部件
            List<Equipment> taBjEq = mapper.queryNewComponent();
            // 改变部件名字
            taBjEq.stream().forEach(b -> b.setName(StrUtil.replace(b.getName(), b.getParentName(), "")));
            List<String> collect = taBjEq.stream().map(Equipment::getId).collect(Collectors.toList());
            List<EquipmentParams> equipmentParams = mapper.queryEqParamsByEqId(collect);
            // 部件id 对应 部件的参数
            Map<String, List<EquipmentParams>> eqIdParamsmap = equipmentParams.stream().collect(Collectors.groupingBy(EquipmentParams::getEquipmentId));

            // 高压线所有塔
            List<Equipment> allTower = mapper.queryAllTower();


            List<Equipment> insertbjlist = new ArrayList();
            List<EquipmentParams> insertbjprarmlist = new ArrayList();
            String yyyyMMdd = DateUtil.format(new Date(), "yyyyMMdd") + "部件导入";
            int num = 1;
            // 遍历所有塔
            for (Equipment equipment : allTower) {
                // 塔为父级
                Equipment parent = equipment;
                // 塔id
                int sort = 1;
                for (Equipment gu7bj : taBjEq) {
                    Equipment bj = new Equipment();
                    BeanUtil.copyProperties(gu7bj, bj);
                    bj.setName(equipment.getName() + bj.getName());
                    bj.setId(CodeTools.getCode32());
                    bj.setSort(sort);
                    bj.setParentName(parent.getName());
                    bj.setParentId(parent.getId());
                    // 父级level+1
                    bj.setLevel(parent.getLevel() + 1);
                    bj.setFullPathCode(parent.getFullPathCode() + "/" + bj.getId());
                    bj.setFullPathName(parent.getFullPathName() + "/" + bj.getName());
                    bj.setIsVirtual("0");
                    int floor = Integer.valueOf(parent.getFloor()) + 1;
                    bj.setFloor(String.valueOf(floor));
                    bj.setLevelCode(sort);
                    bj.setLevelPath(parent.getLevelPath() + "/" + sort);
                    bj.setCode(getCode(num));
                    bj.setDataSources(yyyyMMdd);
                    insertbjlist.add(bj);

                    List<EquipmentParams> tabjparams = eqIdParamsmap.get(gu7bj.getId());
                    // 遍历部件相应参数
                    for (EquipmentParams bjparammo : tabjparams) {
                        EquipmentParams bjparam = new EquipmentParams();
                        BeanUtil.copyProperties(bjparammo, bjparam);
                        // 安装位置
                        if (bjparam.getParamId().equals("bb9234e1a8d94e8da4c0da10d6c13c54")) {
                            String locationId = locationNameIdmap.get(parent.getName());
                            // 相依塔名称 能在 位置表 找到 补充位置id
                            if (StrUtil.isNotBlank(locationId)) {
                                bjparam.setParamValue(parent.getName());
                                bjparam.setParamResult(locationId);
                            } else {
                                bjparam.setParamValue(null);
                                bjparam.setParamResult(null);
                            }
                        }
                        if (bjparam.getParamId().equals("1462606222921375746")) {
                            bjparam.setParamValue(null);
                            bjparam.setParamResult(null);
                        }
                        bjparam.setId(CodeTools.getCode32());
                        bjparam.setEquipmentId(bj.getId());
                        bjparam.setDataSources(yyyyMMdd);
                        insertbjprarmlist.add(bjparam);
                    }
                    sort = sort + 1;
                    num = num + 1;
                }
            }

            Lists.partition(insertbjlist, 300).stream().forEach(p -> {
                mapper.batchInsert(p);
            });
            Lists.partition(insertbjprarmlist, 300).stream().forEach(p -> {
                mapper.batchInsertParams(p);
            });
            return true;
        }, Boolean.class);


        return "结束";
    }


    @ApiOperation("补充高压线10kV分水线路部件")
    @GetMapping("/bugyz10kvbj")
    public String bugyz10kvbj() {

        ADOConnection.runTask(getCurrUser().getCurrDs(), factory -> {
            EquipmentMapper mapper = factory.getMapper(EquipmentMapper.class);
            EquipmentLocationMapper locationMapper = factory.getMapper(EquipmentLocationMapper.class);
            List<EquipmentLocation> equipmentLocations = locationMapper.queryAll();
            // 地点名称-地点id-map
            Map<String, String> locationNameIdmap = equipmentLocations.stream().collect(Collectors.toMap(EquipmentLocation::getName, EquipmentLocation::getId, (e1, e2) -> e1));


            // 查出补充部件
            List<Equipment> taBjEq = mapper.queryBasicComponent();
            // 改变部件名字
            taBjEq.stream().forEach(b -> b.setName(StrUtil.replace(b.getName(), b.getParentName(), "")));
            List<String> collect = taBjEq.stream().map(Equipment::getId).collect(Collectors.toList());
            List<EquipmentParams> equipmentParams = mapper.queryEqParamsByEqId(collect);
            // 部件id 对应 部件的参数
            Map<String, List<EquipmentParams>> eqIdParamsmap = equipmentParams.stream().collect(Collectors.groupingBy(EquipmentParams::getEquipmentId));

            // 高压线所有塔
            List<Equipment> allTower = mapper.queryTenKvTower();


            List<Equipment> insertbjlist = new ArrayList();
            List<EquipmentParams> insertbjprarmlist = new ArrayList();
            String yyyyMMdd = DateUtil.format(new Date(), "yyyyMMdd") + "部件导入";
            int num = 1;
            // 遍历所有塔
            for (Equipment equipment : allTower) {
                // 塔为父级
                Equipment parent = equipment;
                // 塔id
                String id = equipment.getId();
                int sort = 1;
                for (Equipment gu7bj : taBjEq) {
                    Equipment bj = new Equipment();
                    BeanUtil.copyProperties(gu7bj, bj);
                    bj.setName(equipment.getName() + bj.getName());
                    bj.setId(CodeTools.getCode32());
                    bj.setSort(sort);
                    bj.setParentName(parent.getName());
                    bj.setParentId(parent.getId());
                    // 父级level+1
                    bj.setLevel(parent.getLevel() + 1);
                    bj.setFullPathCode(parent.getFullPathCode() + "/" + bj.getId());
                    bj.setFullPathName(parent.getFullPathName() + "/" + bj.getName());
                    bj.setIsVirtual("0");
                    int floor = Integer.valueOf(parent.getFloor()) + 1;
                    bj.setFloor(String.valueOf(floor));
                    bj.setLevelCode(sort);
                    bj.setLevelPath(parent.getLevelPath() + "/" + sort);
                    bj.setCode(getCode(num));
                    bj.setDataSources(yyyyMMdd);
                    insertbjlist.add(bj);

                    List<EquipmentParams> tabjparams = eqIdParamsmap.get(gu7bj.getId());
                    // 遍历部件相应参数
                    for (EquipmentParams bjparammo : tabjparams) {
                        EquipmentParams bjparam = new EquipmentParams();
                        BeanUtil.copyProperties(bjparammo, bjparam);
                        // 安装位置
                        if (bjparam.getParamId().equals("bb9234e1a8d94e8da4c0da10d6c13c54")) {
                            String locationId = locationNameIdmap.get(parent.getName());
                            // 相依塔名称 能在 位置表 找到 补充位置id
                            if (StrUtil.isNotBlank(locationId)) {
                                bjparam.setParamValue(parent.getName());
                                bjparam.setParamResult(locationId);
                            } else {
                                bjparam.setParamValue(null);
                                bjparam.setParamResult(null);
                            }
                        }
                        if (bjparam.getParamId().equals("1462606222921375746")) {
                            bjparam.setParamValue(null);
                            bjparam.setParamResult(null);
                        }
                        bjparam.setId(CodeTools.getCode32());
                        bjparam.setEquipmentId(bj.getId());
                        bjparam.setDataSources(yyyyMMdd);
                        insertbjprarmlist.add(bjparam);
                    }
                    sort = sort + 1;
                    num = num + 1;
                }
            }

//            int size = insertbjlist.size();
//            log.info(size);
//            long count = insertbjlist.stream().map(BaseBean::getId).distinct().count();
//            log.info(count);

            Lists.partition(insertbjlist, 300).stream().forEach(p -> {
                mapper.batchInsert(p);
            });
            Lists.partition(insertbjprarmlist, 300).stream().forEach(p -> {
                mapper.batchInsertParams(p);
            });
            return true;
        }, Boolean.class);


        return "结束";
    }


    /**
     * 导出参数
     * @param id        导出设备的顶级节点
     * @param response
     */
    @ApiOperation("导出设备参数")
    @GetMapping("/exportParam")
    public void exportParam(@RequestParam(value = "id") String id,
                            @RequestParam(value = "name") String name,
                            @RequestParam(value = "groupId") String groupId,
                            @RequestParam(value = "groupName") String groupName, HttpServletResponse response) {

        final Workbook workbook = ADOConnection.runTask(getCurrUser().getCurrDs(), factory -> {
            final Workbook workbooktemp = equipmentservice.getSheets(id, null, groupId, factory);
            return workbooktemp;
        }, Workbook.class);

        name = StrUtil.replace(name, ".", "·");
        final String xlsFileName = StrUtil.join("",DateUtil.today(), PinyinUtil.getFirstLetter(name,""), ".xls");
        EqExportOrImpUtils.downLoadExcel(xlsFileName, response, workbook);
        //动态合并纵列[mergeMap key列索引(从0开始),value依赖的列,没有传空,startRow 开始行(从零开始)]
        //Map<Integer, int[]> mer = new HashMap<>();
        //mer.put(0, new int[]{});
        //PoiMergeCellUtil.mergeCells(workbook.getSheetAt(0), mer, 1);
    }

    /**
     * 获取线路设备树
     */
    @ApiOperation("获取线路设备树")
    @GetMapping("/getLineTree")
    public Response<Equipment> getLineTree(@CasUser @ApiIgnore EamUser user) {
        Map<String, String> config = ConfigInfoTool.getConfigByCode("equipment", "line_root_device");
        String id = config.get("id");
        Equipment equipment = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getUpTreeById", Equipment.class, id);
        return Response.ok(equipment);
    }

    @PostMapping("/getByViewType")
    @ApiOperation(value = "工艺专业视图")
    public String getByViewType(@CasUser @ApiIgnore EamUser user, @RequestBody EquipmentQuery query) {
        List result  = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getByViewType", List.class, query);
        return FastJsonUtils.toJSONStringNoNull(Response.ok(result));
//        return Response.ok(result);
    }

    @GetMapping("/getLineTreeLazy")
    @ApiOperation(value = "查询线路设备台账树形结构（懒加载）, configRules：属性值，不传参则只查询线路")
    public Response<List<LineEquipmentVo>> getLineTreeLazy(@CasUser @ApiIgnore EamUser user, EquipmentQuery query) {
        query.getConfigRules().add("hasChildren");
        List<LineEquipmentVo> result  = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getLineTreeLazy", List.class, query);
        return Response.ok(result);
    }

    @PostMapping("/getTowerParams")
    @ApiOperation(value = "查询杆塔设备参数")
    public Response<Map<String, Map<String, String>>> getTowerParams(@CasUser @ApiIgnore EamUser user, @RequestBody List<String> equipmentIds) {
        Map<String, Map<String, String>> map  = ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getTowerParams", Map.class, equipmentIds);
        return Response.ok(map);
    }

    /**
     * 设备高级查询
     */
    @ApiOperation("设备高级查询")
    @GetMapping("/advancedQuery")
    public Response<PageInfo<EquipmentPo>> advancedQuery(@CasUser @ApiIgnore EamUser user, PageQuery pageQuery, AdvancedQuery query) {
        return Response.ok(ADOConnection.runTask(user.getCurrDs(), equipmentservice, "advancedQueryEquipment", PageInfo.class, pageQuery, query));
    }

    /**
     * 设备列表查询
     */
    @ApiOperation("设备列表查询")
    @PostMapping("/queryEqlist")
    public Response<PageInfo<Equipment>> querylist(@CasUser @ApiIgnore EamUser user, PageQuery pageQuery, @RequestBody EqParamQuery query) {
        return Response.ok(ADOConnection.runTask(user.getCurrDs(), equipmentservice, "queryEqlist", PageInfo.class, pageQuery, query));
    }


    @GetMapping("/getEquipmentByParentId")
    @ApiOperation(value = "查询设备code,kks编码")
    public Response<List<Equipment>> getEquipmentByParentId(@CasUser @ApiIgnore EamUser user, EquipmentQuery query) {

        return ADOConnection.runTask(user.getCurrDs(), equipmentservice, "getEquipmentByParentId", Response.class, query);
    }

    @ApiOperation("根据参数名模糊匹配获取参数列表")
    @GetMapping("/searchParamsByName")
    @ApiImplicitParams({@ApiImplicitParam(value = "参数名", name = "paramName"),@ApiImplicitParam(value = "参数类型，1:基本参数，2:技术参数", name = "paramType")})
    public Response<List<EquipmentParams>> searchParamsByName(@RequestParam(required = false) String paramName,String paramType) {
        if (StringUtils.isBlank(paramType)){
            return Response.fail("参数类型不能为空!");
        }else {
            if (StringUtils.isNotBlank(paramName)){
                paramName=paramName.replaceAll("%", "\\\\%")
                        .replaceAll("_", "\\\\_");
            }
        }
        List<EquipmentParams> searchParamsByName = ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), equipmentservice, "searchParamsByName", List.class, paramName, paramType);
        ArrayList<EquipmentParams> collect = searchParamsByName.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(
                        Comparator.comparing(e -> e.getParamName()))), ArrayList::new));
        return Response.ok(collect);
    }
    @ApiOperation("台账设备高级查询")
    @GetMapping("/advancedEquipmentQuery")
    public Response<PageInfo<EquipmentPo>> advancedEquipmentQuery(@CasUser @ApiIgnore EamUser user, PageQuery pageQuery, AdvancedQuery query) {
        List<EquipmentParams> paramList =new ArrayList<>();
        if (CollectionUtil.isNotEmpty(query.getParams())){
            for (EquipmentParamsPo equipmentParamsPo:query.getParams()) {
                paramList.addAll(ADOConnection.runTask(user.getCurrDs(), equipmentservice, "searchParamsByName", List.class, equipmentParamsPo.getParamName(), equipmentParamsPo.getParamType()));
            }
        }
        List<EquipmentParamsPo> temp= new ArrayList<>(paramList.size());
        List<EquipmentParamsPo> params = query.getParams();
        if (ObjectUtil.isNotNull(params)) {
            query.setParamSize(params.size());
            if(CollectionUtil.isNotEmpty(paramList)){
                params.stream().forEach(equipmentParamsPo->{
                    paramList.stream().forEach(e->{
                        if (e.getParamName().equals(equipmentParamsPo.getParamName())&&e.getGroup().equals(equipmentParamsPo.getParamType())){
                            final EquipmentParamsPo ep = new EquipmentParamsPo();
                            ep.setParamId(e.getParamId());
                            ep.setParamValue(equipmentParamsPo.getParamValue());
                            ep.setParamName(e.getParamName());
                            ep.setParamResult(equipmentParamsPo.getParamResult());
                            temp.add(ep);
                        }
                    });
                });
                query.setParams(temp);
            }
        }
        return Response.ok(ADOConnection.runTask(user.getCurrDs(), equipmentservice, "advancedEquipmentQuery", PageInfo.class, pageQuery, query));
    }

    @GetMapping("/getByERCode")
    @ApiOperation(value = "根据二维码获取设备")
    public Response<Equipment> getByERCode(@RequestBody ERcodeQuery eRcodeQuery) {
        return ADOConnection.runTask(ThreadLocalContext.get().getCurrDs(), equipmentservice, "getByERCode", Response.class, eRcodeQuery);
    }
}
